﻿using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.IO;

namespace Token.Util
{
    /// <summary>
    /// ToThumbnailImage 的摘要说明
    /// </summary>
    public sealed class ThumbnailImage
    {
        /*  
        Create By lion  
        2003-05-20 19:00  
        Copyright (C) 2004 www.LionSky.Net. All rights reserved. 
        Web: http://www.Lionsky.net ;
        Email: lion-a@sohu.com 
        */


        static Hashtable htMIME = new Hashtable();

        public ThumbnailImage()
        {
            #region htmimes[".jpe"]="image/jpeg";
            htMIME[".jpeg"] = "image/jpeg";
            htMIME[".jpg"] = "image/jpeg";
            htMIME[".png"] = "image/png";
            htMIME[".tif"] = "image/tiff";
            htMIME[".tiff"] = "image/tiff";
            htMIME[".bmp"] = "image/bmp";
            #endregion
            ////调用生成缩略图方法
            //ToThumbnailImages("lionsky.jpg", "b.gif", 300);
        }

        #region Helper

        /// <summary>
        /// 获取图像编码解码器的所有相关信息
        /// </summary>
        /// <param name="mimeType">包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串</param>
        /// <returns>返回图像编码解码器的所有相关信息</returns>
        static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.MimeType == mimeType) return ici;
            }
            return null;
        }

        /// <summary>
        /// 保存图片
        /// </summary>
        /// <param name="image">Image 对象</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="ici">指定格式的编解码参数</param>
        void SaveImage(System.Drawing.Image img, Stream os, ImageCodecInfo ici)
        {
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ((long)90));
            img.Save(os, ici, parameters);
            parameters.Dispose();
        }
        #endregion

        #region Methods

        /// <summary>
        /// 按照原图比例产生缩略图
        /// 输出的缩略图大小最接近但是不会超过 iNewSize * iNewSize
        /// </summary>
        /// <param name="ins">原始图片流。处理完成之后不会自动关闭该流。</param>
        /// <param name="os">缩略图输出流。处理完成之后不会自动关闭该流。</param>
        /// <param name="iNewSize">目标尺寸（宽度或者高度）。</param>
        public void ToThumbnailImage(Stream streamInput, Stream streamOutput, int iNewSize, int imgHeight)
        {
            // 如果目标尺寸为0，则直接输出。
            if (iNewSize <= 0)
            {
                SaveImage(Image.FromStream(streamInput), streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
                return;
            }
            // 计算最合适的输出尺寸
            // 代表原始图片的 Image 对象
            System.Drawing.Image imgOld = System.Drawing.Image.FromStream(streamInput);
            // 长宽都小于targetWidth ?
            if (imgOld.Height <= iNewSize && imgOld.Width <= iNewSize)
            {
                SaveImage(imgOld, streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
                return;
            }
            // 保持图片比例
            double _oldScale = 1.0 * imgOld.Width / imgOld.Height;
            // 过宽还是过高？
            if (_oldScale == 0)
                return;
            if (imgHeight > 0)
            {
                if (imgHeight * _oldScale < iNewSize)
                    iNewSize = (int)(imgHeight * _oldScale);
            }

            int _targetHeight = (int)(iNewSize / _oldScale);

            // 用新的大小和格式初始化 Bitmap 类的新实例
            Bitmap _newBitmap = new Bitmap(iNewSize, _targetHeight, PixelFormat.Format32bppArgb);
            // 从指定的 Image 对象创建新 Graphics 对象
            Graphics _newGraphics = Graphics.FromImage(_newBitmap);
            // 清除整个绘图面并以透明背景色填充
            _newGraphics.Clear(Color.Transparent);
            // 在指定位置并且按指定大小绘制 原图片 对象
            _newGraphics.DrawImage(imgOld, new Rectangle(0, 0, iNewSize, _targetHeight));
            try
            {
                //将此 原图片 以指定格式并用指定的编解码参数保存到stream
                SaveImage(_newBitmap, streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
            }
            finally
            {
                _newBitmap.Dispose();
                _newGraphics.Dispose();
                imgOld.Dispose();
            }

        }


        /// <summary>
        /// 以整洁的方式来展现图片缩略图，原始图片首先尽量被缩略为 不小于 指定长宽的图（比例不变）
        /// </summary>
        /// <param name="streamInput"></param>
        /// <param name="streamOutput"></param>
        /// <param name="iNewSize"></param>
        /// <param name="imgHeight"></param>
        /// <param name="tidy"></param>
        public void ToThumbnailImage(Stream streamInput, Stream streamOutput, int iNewSize, int imgHeight, bool tidy)
        {
            if (!tidy)
            {
                ToThumbnailImage(streamInput, streamOutput, iNewSize, imgHeight);

                return;
            }

            // 如果目标尺寸为0，则直接输出。
            if (iNewSize <= 0)
            {
                SaveImage(Image.FromStream(streamInput), streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
                return;
            }

            // 计算最合适的输出尺寸
            // 代表原始图片的 Image 对象
            System.Drawing.Image imgOld = System.Drawing.Image.FromStream(streamInput);
            // 长宽都小于targetWidth ?
            if (imgOld.Height <= imgHeight && imgOld.Width <= iNewSize)
            {
                SaveImage(imgOld, streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
                return;
            }
            // 保持图片比例
            double _oldScale = 1.0 * imgOld.Width / imgOld.Height;
            // 过宽还是过高？
            if (_oldScale == 0)
                return;
            if (imgHeight > 0)
            {
                if (imgHeight * _oldScale > iNewSize)
                    iNewSize = (int)(imgHeight * _oldScale);
            }

            int _targetHeight = (int)(iNewSize / _oldScale);

            // 用新的大小和格式初始化 Bitmap 类的新实例
            Bitmap _newBitmap = new Bitmap(iNewSize, _targetHeight, PixelFormat.Format32bppArgb);
            // 从指定的 Image 对象创建新 Graphics 对象
            Graphics _newGraphics = Graphics.FromImage(_newBitmap);
            // 清除整个绘图面并以透明背景色填充
            _newGraphics.Clear(Color.Transparent);

            // 在指定位置并且按指定大小绘制 原图片 对象
            _newGraphics.DrawImage(imgOld, new Rectangle(0, 0, iNewSize, _targetHeight));

            try
            {
                //将此 原图片 以指定格式并用指定的编解码参数保存到stream
                SaveImage(_newBitmap, streamOutput, GetCodecInfo((string)htMIME[".jpg"]));
            }
            finally
            {
                _newBitmap.Dispose();
                _newGraphics.Dispose();

                imgOld.Dispose();
            }

        }
        #endregion

        /// <summary>
        /// 返回指定大小的图片
        /// </summary>
        /// <param name="streamInput"></param>
        /// <param name="img"></param>
        /// <param name="iNewSize"></param>
        /// <param name="imgHeight"></param>
        public void ToThubnailimagNoSave(Stream streamInput, ref System.Drawing.Image img, int iNewSize, int imgHeight)
        {
            // 如果目标尺寸为0，则直接输出。
            if (iNewSize <= 0)
            {
                return;
            }
            // 计算最合适的输出尺寸
            // 代表原始图片的 Image 对象
            System.Drawing.Image imgOld = System.Drawing.Image.FromStream(streamInput);
            img = imgOld;
            // 长宽都小于targetWidth ?
            if (imgOld.Height <= iNewSize && imgOld.Width <= iNewSize)
            {
                return;
            }
            // 保持图片比例
            double _oldScale = 1.0 * imgOld.Width / imgOld.Height;
            // 过宽还是过高？
            if (_oldScale == 0)
            {
                return;
            }
            int _targetHeight = iNewSize;

            if (imgHeight > 0)
            {
                if (imgHeight * _oldScale < iNewSize)
                    iNewSize = (int)(imgHeight * _oldScale);

                _targetHeight = (int)(iNewSize / _oldScale);
            }
            // 用新的大小和格式初始化 Bitmap 类的新实例
            Bitmap _newBitmap = new Bitmap(iNewSize, _targetHeight, PixelFormat.Format32bppArgb);
            // 从指定的 Image 对象创建新 Graphics 对象
            Graphics _newGraphics = Graphics.FromImage(_newBitmap);
            // 清除整个绘图面并以透明背景色填充
            _newGraphics.Clear(Color.Transparent);
            // 在指定位置并且按指定大小绘制 原图片 对象
            _newGraphics.DrawImage(imgOld, new Rectangle(0, 0, iNewSize, _targetHeight));

            img = Image.FromHbitmap(_newBitmap.GetHbitmap());
            _newBitmap.Dispose();
            _newGraphics.Dispose();
            imgOld.Dispose();
            return;
        }

    }


}